home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
filesyst
/
thsfs.tgz
/
thsfs.tar
/
thsfs
/
kompr1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-04
|
4KB
|
261 lines
/*************************************************************
* *
* ths Filesystem 04.10.94 V1.1 *
* *
* Thomas Scheuermann ths@ai-lab.fh-furtwangen.de *
* *
*************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/locks.h>
#include <linux/fs.h>
#include <linux/malloc.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/bitops.h>
#include "ths.h"
#include "ths_i.h"
/*
* Dekompressionsalgorithmus
* funktioniert nur mit Komprimierung 2
*/
void decompress(struct super_block *s, struct ths_buffer *tbf, int mdfat)
{
unsigned char zc,zu,flag,*data=NULL;
unsigned long sektor;
struct buffer_head *bh;
int i,k,rb,rl,hz,m,sek,sekmax;
#ifdef DEBUG
printk("decompress %d\n",mdfat);
#endif
sektor = (mdfat & 0x1fffff) +1;
sekmax = ((mdfat & 0x3c000000)>>26) +1;
/*
* i : Bitzaehler
* k : Zeichenzaehler dekomprimiert
* hz : Hilfszaehler fuer Bits;
* rb : Rueckwaertsbezug rb Bytes
* rl : Laenge des Rueckwaertsbezugs
* m : Laengenhilfsspeicher
* flag : Status
* zc : komprimiertes Zeichen
* zu : unkomprimiertes Zeichen
* sek : Sektorzaehler
*/
k=0;
zu=0;
zc=0;
rb=0;
rl=0;
hz=0;
m=0;
sek = 0;
flag = 'n';
for(i=0;sek<sekmax;)
{
if(!(i%8))
{
if(!(i%4096))
{
data = ths_uread(s,sektor+i/4096,&bh);
}
if(!i)
{
if(data[0]!=0x44 && data[1]!=0x53 && data[2]!=0x00 && data[3]!=0x02)
{
printk("Komprimierung nicht erkannt!!\n");
return;
}
i=32;
}
zc = data[(i/8)%512];
}
switch(flag)
{
case 'n': /* neu */
if(zc&1)
flag = 'I';
else
flag = 'O';
zc >>= 1;
break;
case 'I': /* erstes Bit 1 */
if(zc&1)
flag = 'r';
else
{
flag = 'L';
hz = 7;
}
zc >>= 1;
break;
case 'O': /* erstes Bit 0 */
if(zc&1)
{
flag = 'l';
hz=7;
}
else
{
flag = 'A';
hz = 6;
rb = 0;
}
zc >>= 1;
break;
case 'l': /* Zeichen 0 - 127 */
if(zc&1)
zu |=0x80;
zu >>= 1;
zc >>= 1;
if(!(--hz))
{
flag ='n';
(tbf->data[k/512])[k%512] = zu;
k++;
zu=0;
}
break;
case 'L': /* Zeichen 128 - 255 */
if(zc&1)
zu |=0x80;
zu >>= 1;
zc >>= 1;
if(!(--hz))
{
zu |=0x80;
flag ='n';
(tbf->data[k/512])[k%512] = zu;
k++;
zu=0;
}
break;
case 'r': /* Rueck ? */
if(zc&1)
{
flag = 'C';
hz = 12;
rb = 0;
}
else
{
flag = 'B';
hz = 8;
rb = 0;
}
zc >>= 1;
break;
case 'A': /* 6 Bit rueckwarts */
if(zc&1)
rb |=0x40;
rb >>= 1;
zc >>= 1;
if(!(--hz))
{
flag ='X';
}
break;
case 'B': /* 8 Bit rueckwarts */
if(zc&1)
rb |=0x100;
rb >>= 1;
zc >>= 1;
if(!(--hz))
{
flag ='X';
rb += 64;
}
break;
case 'C': /* 12 Bit rueckwarts */
if(zc&1)
rb |=0x1000;
rb >>= 1;
zc >>= 1;
if(!(--hz))
{
if(rb==0xfff)
{
sek++;
flag = 'n';
break;
}
flag ='X';
rb +=320;
}
break;
case 'X': /* Trefferlaenge, 0 zaehlen */
if(zc&1)
{
flag = 'Y';
rl =0;
m = 1;
m <<=hz;
if(m==1)
{
flag = 'n';
(tbf->data[k/512])[k%512] = (tbf->data[(k-rb)/512])[(k-rb)%512];
k++;
(tbf->data[k/512])[k%512] = (tbf->data[(k-rb)/512])[(k-rb)%512];
k++;
}
}
else
{
hz++;
}
zc >>= 1;
break;
case 'Y': /* Trefferlaenge berechnen */
if(!(--hz))
{
if(zc&1)
rl |= m;
rl >>= 1;
rl = rl + m + 1;
for(hz=0;hz<rl;hz++)
{
(tbf->data[k/512])[k%512] = (tbf->data[(k-rb)/512])[(k-rb)%512];
k++;
}
flag = 'n';
}
else
{
if(zc&1)
rl |= m;
rl >>= 1;
}
zc >>= 1;
break;
}
i++;
if(!(i%4096))
{
brelse(bh);
}
}
if((i%4096))
{
brelse(bh);
}
return;
}